﻿using Algorithm.Check;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static Algorithm.Check.ExtensionForCRC16;
using static OfficeOpenXml.ExcelErrorValue;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace NewDevice.RS485
{
    public class YPF_40R
    {
        private readonly OldSerialBase _serial;
        private readonly int _slaveId;
        private readonly string _deviceName;

        public YPF_40R(OldSerialBase bus, int slaveId, string name = "英鹏飞电机", ZH_NumericDisplayFormat format = ZH_NumericDisplayFormat.FixedThreeDecimal)
        {
            _serial = bus;
            this._slaveId = slaveId;
            this._deviceName = name;
        }

        /// <summary>
        /// 写入运行速度
        /// </summary>
        public void SetRunSpeed(int value)
        {
            byte[] bytes = BitConverter.GetBytes((ushort)value); // 转成2字节（ushort）
            if (BitConverter.IsLittleEndian) // 检查字节序（小端序需反转）
            {
                Array.Reverse(bytes);
            }

            byte[] data = [
                (byte)_slaveId,
                0x06,0x00,0x9A
            ];
            byte[] mergedArray = data.Concat(bytes).ToArray();
            byte[] cmd = mergedArray.WithCRC16(CRC16Type.Modbus).ToArray();
            _serial.deviceName = _deviceName;
            var recv = _serial.SendBytesAndWaitResponse(cmd, ReceivedDataCheck.FuncModbusCRC16Check);
        }

        /// <summary>
        /// 写入停止速度,已写入0，不启用
        /// </summary>
        public void SetStopSpeed()
        {
        }

        /// <summary>
        /// 清除电机报警状态
        /// </summary>
        public void ClearWarining()
        {
            byte[] data = new byte[] {
                (byte)_slaveId,
                0x06,0x00,0xA4,0x00,0x00
            };

            byte[] cmd = data.WithCRC16(CRC16Type.Modbus).ToArray();
            _serial.deviceName = _deviceName;
            var recv = _serial.SendBytesAndWaitResponse(cmd, ReceivedDataCheck.FuncModbusCRC16Check);
        }

        /// <summary>
        /// 读取电机报警状态
        /// </summary>
        public string ReadWarining()
        {
            byte[] data = new byte[] {
                (byte)_slaveId,
                0x03,0x00,0xA3,0x00,0x01
            };

            byte[] cmd = data.WithCRC16(CRC16Type.Modbus).ToArray();
            _serial.deviceName = _deviceName;
            byte[] recv = _serial.SendBytesAndWaitResponse(cmd, ReceivedDataCheck.FuncModbusCRC16Check);

            // 解析第4位（索引3）和第5位（索引4）
            int decimalValue = recv[3] << 8 | recv[4];
            return converWaring(decimalValue);
        }

        /// <summary>
        /// 报警转化
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public string converWaring(int index)
        {
            switch (index)
            {
                case 0:
                    return "正常";

                case 1:
                    return "电机相位过流";

                case 2:
                    return "供电电压过高";

                case 3:
                    return "供电电压过低";

                case 4:
                    return "电机A相开路";

                case 5:
                    return "电机B相开路";

                case 6:
                    return "其他报警或位置超差";

                case 7:
                    return "内部24V电压偏移";

                case 8:
                    return "AI电压错误";

                case 9:
                    return "BI电压错误";

                case 10:
                    return "编码器错误";

                default:
                    return "其他错误";
            }
        }

        /// <summary>
        /// 退出
        /// </summary>
        public void Dispose()
        {
            _serial.Close();
            _serial.Dispose();
        }

        /// <summary>
        /// 启动
        /// </summary>
        public void Run()
        {
            byte[] data = [
                (byte)_slaveId,
                0x06,0x00,0xC8,0x00,0x01
            ];
            byte[] cmd = data.WithCRC16(CRC16Type.Modbus).ToArray();
            _serial.deviceName = _deviceName;
            var recv = _serial.SendBytesAndWaitResponse(cmd, ReceivedDataCheck.FuncModbusCRC16Check);
        }

        /// <summary>
        /// 反向启动
        /// </summary>
        public void RunReverse()
        {
            byte[] data = new byte[] {
                (byte)_slaveId,
                0x06,0x00,0xC8,0x01,0x01
            };
            byte[] cmd = data.WithCRC16(CRC16Type.Modbus).ToArray();
            _serial.deviceName = _deviceName;
            var recv = _serial.SendBytesAndWaitResponse(cmd, ReceivedDataCheck.FuncModbusCRC16Check);
        }

        /// <summary>
        /// 紧急停止
        /// </summary>
        public void EmsStop()
        {
            byte[] data = new byte[] {
                (byte)_slaveId,
                0x06,0x00,0xC8,0x01,0x00
            };

            byte[] cmd = data.WithCRC16(CRC16Type.Modbus).ToArray();
            _serial.deviceName = _deviceName;
            var recv = _serial.SendBytesAndWaitResponse(cmd, ReceivedDataCheck.FuncModbusCRC16Check);
        }

        /// <summary>
        /// 停止
        /// </summary>
        public void Stop()
        {
            byte[] data = [
                (byte)_slaveId,
                0x06,0x00,0xC8,0x00,0x00
            ];

            byte[] cmd = data.WithCRC16(CRC16Type.Modbus).ToArray();
            _serial.deviceName = _deviceName;
            var recv = _serial.SendBytesAndWaitResponse(cmd, ReceivedDataCheck.FuncModbusCRC16Check);
        }

        /// <summary>
        /// 设置减速时间,单位ms
        /// </summary>
        public void SetStopTime(int TimeOut)
        {
            byte[] bytes = BitConverter.GetBytes((ushort)TimeOut); // 转成2字节（ushort）
            if (BitConverter.IsLittleEndian) // 检查字节序（小端序需反转）
            {
                Array.Reverse(bytes);
            }

            byte[] data = [
                (byte)_slaveId,
                0x06,0x00,0x99
            ];
            byte[] mergedArray = data.Concat(bytes).ToArray();
            byte[] cmd = mergedArray.WithCRC16(CRC16Type.Modbus).ToArray();
            _serial.deviceName = _deviceName;
            var recv = _serial.SendBytesAndWaitResponse(cmd, ReceivedDataCheck.FuncModbusCRC16Check);
        }

        /// <summary>
        /// 按照时长运行,单位ms
        /// </summary>
        public void RunByTime(int TimeOut)
        {
            byte[] bytes = ConvertToCustomBytes(TimeOut);

            byte[] data = [
                (byte)_slaveId,
                0x10,0x00,0xCC,0x00,0X02,0X04
            ];
            byte[] mergedArray = data.Concat(bytes).ToArray();
            byte[] cmd = mergedArray.WithCRC16(CRC16Type.Modbus).ToArray();
            _serial.deviceName = _deviceName;
            var recv = _serial.SendBytesAndWaitResponse(cmd, ReceivedDataCheck.FuncModbusCRC16Check);
        }

        /// <summary>
        /// 字节转化
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private byte[] ConvertToCustomBytes(int value)
        {
            byte[] bytes = new byte[4];
            bytes[0] = (byte)(value >> 8); // 第 4 字节 (00)
            bytes[1] = (byte)(value & 0xFF); // 第 3 字节 (00)
            bytes[2] = (byte)(value >> 24);  // 第 2 字节 (02)
            bytes[3] = (byte)(value >> 16); // 第 1 字节 (52)
            return bytes;
        }

        /// <summary>
        /// 按照脉冲当量运行，不启用
        /// </summary>
        public void RunByPulse()
        {
        }
    }
}